using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WPCoco.Tasks
{
    public class TimeSpawn : FiniteTime, IContainer<Task>
    {
        public TimeSpawn(params FiniteTime[] tasks)
            : base(0)
        {
            this.tasks = tasks;
            initialized = new bool[tasks.Length];
            finished = new bool[tasks.Length];
            duration = new float[tasks.Length];
            UpdateTimeLine();
        }

        FiniteTime[] tasks;
        bool[] initialized;
        bool[] finished;
        float[] duration;

        void UpdateTimeLine()
        {
            float max = 0;
            for (int i = 0; i < tasks.Length; i++)
            {
                initialized[i] = false;
                finished[i] = false;
                duration[i] = tasks[i].Duration;
                max = Math.Max(max, duration[i]);
            }
            Duration = max;
        }

        public override void Initialize()
        {
            base.Initialize();
            UpdateTimeLine();
        }

        public override void Update(float time)
        {
            base.Update(time);
            if (HasEnded()) return;
            for (int i = 0; i < tasks.Length; i++)
            {
                if (!initialized[i]) 
                {
                    initialized[i] = true;
                    tasks[i].Initialize();
                }
                if (tasks[i].HasEnded())
                {
                    if (!finished[i])
                    {
                        finished[i] = true;
                        tasks[i].Update(duration[i]);
                        tasks[i].Finish();
                    }
                    continue;
                }
                tasks[i].Update(time);
            }
        }

        public override void Finish()
        {
            for (int i = 0; i < tasks.Length; i++)
            {
                if (!initialized[i])
                    tasks[i].Initialize();
                if (!finished[i])
                {
                    tasks[i].Update(duration[i]);
                    tasks[i].Finish();
                }
            }
        }

        public override Task Clone()
        {
            FiniteTime[] innerCloned = new FiniteTime[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
                innerCloned[i] = tasks[i].Clone() as FiniteTime;
            TimeSpawn task = new TimeSpawn(innerCloned);
            return task;
        }

        public override Task Reverse()
        {
            FiniteTime[] innerCloned = new FiniteTime[tasks.Length];
            for (int i = 0; i < tasks.Length; i++)
                innerCloned[i] = tasks[i].Reverse() as FiniteTime;
            TimeSpawn task = new TimeSpawn(innerCloned);
            return task;
        }

        #region IContainer<Task> Members

        public IEnumerable<Task> GetContainerEnumerator()
        {
            for (int i = 0; i < tasks.Length; i++)
                yield return tasks[i];
            yield break;
        }

        #endregion
    }
}
